/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package client.gui;

import clientside.ControlClientSide;
import clientside.DataClientSide;
import com.cse.p2p.common.DicFile;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.io.File;
import java.util.Random;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileFilter;

/**
 *
 * @author TrungHieu
 */
public class UploadView extends JFrame {

	public JButton fireButton;
	private GridBagConstraints c;
	private JTextField txtFileURI, txtDicFileURI;
	private JButton btnSelectFile, btnDicFileSaveTo, btnOK, btnCancel, btnHide;
	private JLabel lblTxtFileSize, lblTxtCurrentAction;
	private JTextArea txtFileDesc;
	private JFileChooser fileChooser;
	private JPanel mainPanel;
	private JProgressBar progressBar;
	private JFrame deamon;
	private ActionListener startUploadLst;
	private ControlClientSide controlThread;
	private DataClientSide dataThread;
	/**
	 * The monitoring thread
	 */
	UploadProgressMonitor uploadMonitorThread = null;

	public UploadView( JButton fireButton, ControlClientSide cThread, DataClientSide dThread ) {
		super( "Create new DicFile" );
		this.fireButton = fireButton;
		this.fireButton.setEnabled( false );
		this.controlThread = cThread;
		this.dataThread = dThread;
		Dimension txtFieldPrefDim = new Dimension( 600, 24 );
		fileChooser = new JFileChooser();

		mainPanel = new JPanel( new GridBagLayout() );
		mainPanel.setBorder( new EmptyBorder( 10, 10, 10, 10 ) );
		this.getContentPane().add( mainPanel );
		c = new GridBagConstraints();
		c.ipadx = 6;
		c.ipady = 6;
		c.anchor = GridBagConstraints.LINE_START;

		JLabel lblFileURI = new JLabel( "File to upload" );
		c.gridx = 0;
		c.gridy = 0;
		mainPanel.add( lblFileURI, c );

		txtFileURI = new JTextField();
		txtFileURI.setPreferredSize( txtFieldPrefDim );
		c.gridx = 1;
		c.gridy = 0;
		mainPanel.add( txtFileURI, c );

		btnSelectFile = new JButton( "Browse..." );
		btnSelectFile.addActionListener( new ActionListener() {

			@Override
			public void actionPerformed( ActionEvent e ) {
				fileChooser.setFileFilter( null );
				fileChooser.setAcceptAllFileFilterUsed( true );
				int returnVal = fileChooser.showOpenDialog( mainPanel );
				if ( returnVal == JFileChooser.APPROVE_OPTION ) {
					File file = fileChooser.getSelectedFile();
					txtFileURI.setText( file.getAbsolutePath() );
				}
			}
		} );
		c.gridx = 2;
		c.gridy = 0;
		mainPanel.add( btnSelectFile, c );

		JLabel lblDicFileURI = new JLabel( "Save DicFile to" );
		c.gridx = 0;
		c.gridy = 1;
		mainPanel.add( lblDicFileURI, c );

		txtDicFileURI = new JTextField();
		txtDicFileURI.setPreferredSize( txtFieldPrefDim );
		c.gridx = 1;
		c.gridy = 1;
		mainPanel.add( txtDicFileURI, c );

		btnDicFileSaveTo = new JButton( "Browse..." );
		btnDicFileSaveTo.addActionListener( new ActionListener() {

			@Override
			public void actionPerformed( ActionEvent e ) {
				fileChooser.setFileFilter( new FileFilter() {

					@Override
					public boolean accept( File f ) {
						if ( f.isDirectory() ) {
							return true;
						}
						String fileName = f.getName();
						int pos = fileName.lastIndexOf( "." );
						if ( pos < 0 ) {
							return false;
						}
						return fileName.substring( pos ).equalsIgnoreCase( "." + DicFile.FILE_EXT );
					}

					@Override
					public String getDescription() {
						return DicFile.FILE_EXT_DESC;
					}
				} );
				fileChooser.setAcceptAllFileFilterUsed( false );
				boolean finish = true;
				do {
					int returnVal = fileChooser.showSaveDialog( mainPanel );
					if ( returnVal == JFileChooser.APPROVE_OPTION ) {
						File file = fileChooser.getSelectedFile();
						if ( file.exists() ) {
							finish = false;
							if ( JOptionPane.showOptionDialog( mainPanel, "The selected file exists. Do you want to replace it with the new Dic file?",
															   "File exists", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
															   null, null, null ) == JOptionPane.YES_OPTION ) {
								finish = true;
							};
						}
						String path = file.getAbsolutePath();
						if ( !file.getName().endsWith( "." + DicFile.FILE_EXT ) ) {
							path = path + "." + DicFile.FILE_EXT;
						};
						txtDicFileURI.setText( path );
					}
				}
				while ( !finish );
			}
		} );
		c.gridx = 2;
		c.gridy = 1;
		mainPanel.add( btnDicFileSaveTo, c );

		JLabel lblFileSize = new JLabel( "File size" );
		c.gridx = 0;
		c.gridy = 2;
		mainPanel.add( lblFileSize, c );

		lblTxtFileSize = new JLabel();
		c.gridx = 1;
		c.gridy = 2;
		mainPanel.add( lblTxtFileSize, c );

		JLabel lblFielDesc = new JLabel( "Description (optional)" );
		c.gridx = 0;
		c.gridy = 3;
		c.gridwidth = 3;
		mainPanel.add( lblFielDesc, c );

		txtFileDesc = new JTextArea();
		txtFileDesc.setLineWrap( true );
		txtFileDesc.setWrapStyleWord( true );
		txtFileDesc.setBackground( Color.WHITE );
		txtFileDesc.setOpaque( true );
		JScrollPane pnlFileDescHolder = new JScrollPane( txtFileDesc );
		pnlFileDescHolder.setPreferredSize( new Dimension( 600, 120 ) );
		c.gridx = 1;
		c.gridy = 4;
		mainPanel.add( pnlFileDescHolder, c );

		c.gridx = 0;
		c.gridy = 5;
		mainPanel.add( Box.createVerticalStrut( 20 ), c );

		lblTxtCurrentAction = new JLabel( "Ready" );
		c.gridx = 0;
		c.gridy = 6;
		c.gridwidth = 3;
		mainPanel.add( lblTxtCurrentAction, c );

		progressBar = new JProgressBar( 0, 100 );
		progressBar.setIndeterminate( true );
		progressBar.setValue( 0 );
		progressBar.setStringPainted( false );
		c.gridx = 0;
		c.gridy = 7;
		c.fill = GridBagConstraints.HORIZONTAL;
		mainPanel.add( progressBar, c );

		JPanel footerPnl = new JPanel( new FlowLayout( FlowLayout.RIGHT ) );


		btnOK = new JButton( "Start" );
		uploadMonitorThread = new UploadProgressMonitor( lblTxtCurrentAction, progressBar,
														 txtFileURI, txtDicFileURI, txtFileDesc, btnOK );
		footerPnl.add( btnOK );
		startUploadLst = new ActionListener() {

			@Override
			public void actionPerformed( ActionEvent e ) {

				uploadMonitorThread.start();
			}
		};
		btnOK.addActionListener( startUploadLst );
		btnHide = new JButton( "Hide" );
		footerPnl.add( btnHide );
		btnCancel = new JButton( "Cancel" );
		btnCancel.addActionListener( new OnStopListener( this, uploadMonitorThread ) );
		footerPnl.add( btnCancel );

		c.gridx = 0;
		c.gridy = 8;
		c.fill = GridBagConstraints.HORIZONTAL;
		mainPanel.add( footerPnl, c );
	}

//	private void updateProgress(int value){
//		this.progressBar.setValue( value );
//		this.progressBar.repaint();
//	}
	private class UploadProgressMonitor extends Thread {

		private JLabel lblIndicator;
		private JProgressBar prgIndicator;
		private JTextField rootPath;
		private JTextField targetPath;
		private JTextArea fileDesc;
		private JButton fireButton;
		private volatile boolean stop = false;

		public UploadProgressMonitor( JLabel lableIndicator, JProgressBar progressIndicator,
									  JTextField rootPath, JTextField targetPath, JTextArea fileDesc,
									  JButton fireButton ) {
			super();
			this.lblIndicator = lableIndicator;
			this.prgIndicator = progressIndicator;
			this.rootPath = rootPath;
			this.targetPath = targetPath;
			this.fileDesc = fileDesc;
			this.fireButton = fireButton;
		}

		@Override
		public void run() {
			// use the demo - replace this by your functions
			action();
			if ( stop ) {
				System.out.println( "Interupted" );
			}
			// end the demo 
		}

		private void demo() {
			lblIndicator.setText( "Uploading your file to the server ... " );
			prgIndicator.setIndeterminate( false );
			prgIndicator.setStringPainted( true );
			for ( int i = 0; i <= 100 && !stop; i++ ) {
				prgIndicator.setValue( i );
				prgIndicator.repaint();
				try {
					sleep( ( new Random() ).nextInt( 1000 ) );
				}
				catch ( InterruptedException e ) {
					System.out.println( e.getMessage() );
					e.printStackTrace();
				}
			}

			lblIndicator.setText( "Waiting for the Dic file from server ... " );
			prgIndicator.setValue( 0 );
			prgIndicator.setIndeterminate( true );
			prgIndicator.setStringPainted( false );
			prgIndicator.repaint();
			if ( !stop ) {
				try {
					sleep( 3000 );
				}
				catch ( InterruptedException e ) {
					System.out.println( e.getMessage() );
					e.printStackTrace();
				}
			}

			lblIndicator.setText( "Getting the Dic file ... " );
			prgIndicator.setIndeterminate( false );
			prgIndicator.setStringPainted( true );
			for ( int i = 0; i <= 100 && !stop; i++ ) {
				prgIndicator.setValue( i );
				prgIndicator.repaint();
				try {
					sleep( ( new Random() ).nextInt( 200 ) );
				}
				catch ( InterruptedException e ) {
					System.out.println( e.getMessage() );
					e.printStackTrace();
				}
			}

			lblIndicator.setText( "Saving file ... " );
			lblIndicator.setText( "The Dic file is created and saved successfully." );
		}

		private void action() {

			fireButton.setEnabled( false );
			controlThread.uploadNewFileRoutine( rootPath.getText(), targetPath.getText(), fileDesc.getText(), this.lblIndicator, this.prgIndicator );
		}

		public void requestStop() {
			stop = true;
		}
	}

	private class OnStopListener implements ActionListener {

		private UploadView parent;
		private UploadProgressMonitor progress;

		public OnStopListener( UploadView parent, UploadProgressMonitor progress ) {
			this.parent = parent;
			this.progress = progress;
		}

		@Override
		public void actionPerformed( ActionEvent e ) {
			if ( progress.isAlive() ) {
				int cancel = JOptionPane.showConfirmDialog( parent, "The uploading progress is running, do you want to interupt it?",
															"Confirm your option", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE );
				if ( cancel == JOptionPane.YES_OPTION ) {
					progress.interrupt();
					progress.requestStop();
				}
			}
			parent.setVisible( false );
			parent.fireButton.setEnabled( true );

		}
	}
}
